
package com.borqs.music.executor;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Executor executes all the tasks submitted in a single thread. The working
 * queue is used LinkedBlockingQueue.
 */
public final class MusicExecutor implements RejectedExecutionHandler {

    // Configurable parameters for ThreadPoolExecutor
    private static final int CORE_POOL_SIZE = 3;
    private static final int MAX_POOL_SIZE = 10;
    private static final int KEEP_ALIVE = 10;

    private ThreadPoolExecutor mExecutor;

    private MusicExecutor() {
        BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>(CORE_POOL_SIZE);

        mExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE,
                TimeUnit.SECONDS, blockingQueue);
        mExecutor.setRejectedExecutionHandler(this);
    }

    private static MusicExecutor mInstance;

    public static synchronized MusicExecutor getInstance() {
        if (mInstance == null) {
            mInstance = new MusicExecutor();
        }

        return mInstance;
    }

    public BlockingQueue<Runnable> getQueue() {
        return mExecutor.getQueue();
    }

    public void execute(Task task) {
        mExecutor.execute(task);
    }

    public boolean isShutdown() {
        return mExecutor.isShutdown();
    }

    public void shutdown() {
        mExecutor.shutdown();
    }

    /** {@inheritDoc} */
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // reset the max size
        executor.setMaximumPoolSize(executor.getMaximumPoolSize() + 1);
        executor.execute(r);
    }
    
    public static void executeTask(Task task){
        getInstance().execute(task);
    }
}
